package com.jeediy.khbd.socketDemos;

import com.crazymakercircle.util.IOUtil;
import com.crazymakercircle.util.Logger;
import com.crazymakercircle.util.ThreadUtil;
import com.jeediy.khbd.NioDemoConfig;
import org.apache.commons.lang.CharSet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;

/**
 * 文件传输客户端
 * @author D.Y
 * @description
 * @date 2023/12/7
 */
public class NioSendClient {
    private static final Charset _CHARSET = Charset.forName("UTF-8");

    /**
     * 向服务端发送文件
     */
    public void sendFile(){
        //发送小文件
        String srcPath = NioDemoConfig.SOCKET_SEND_FILE;
        File file = new File(srcPath);
        if(!file.exists()) {
            srcPath= IOUtil.getResourcePath(srcPath);
            Logger.debug("srcPath=" + srcPath);
            file = new File(srcPath);
            if(!file.exists()) {
                Logger.debug("文件不存在");
                return;
            }
        }
        try {
            FileChannel fileChannel = new FileInputStream(file).getChannel();
            SocketChannel socketChannel = SocketChannel.open();
            socketChannel.setOption(StandardSocketOptions.TCP_NODELAY,true);
            socketChannel.socket().connect(
                    new InetSocketAddress(NioDemoConfig.SOCKET_SERVER_IP
                            ,NioDemoConfig.SOCKET_SERVER_PORT)
            );
            //socketChannel.connect();
            //设置为非阻塞
            socketChannel.configureBlocking(false);
            while(!socketChannel.finishConnect()) {
                //不断的自旋、等待或干其他事
            }
            
            //获取文件名称
            ByteBuffer fileNameBuffer = _CHARSET.encode(file.getPath());

            ByteBuffer buffer = ByteBuffer.allocate(NioDemoConfig.SEND_BUFFER_SIZE);

            int fileNameLength = fileNameBuffer.remaining();
            buffer.clear();
            //放入文件名称的长度
            buffer.putInt(fileNameLength);
            //放入文件名称
            buffer.put(fileNameBuffer);
            //切换到读模式
            buffer.flip();
            socketChannel.write(buffer);

            //发送文件长度
            buffer.clear();
            buffer.putInt((int)file.length());
            socketChannel.write(buffer);

            Logger.debug("开始传输文件");
            int length = 0;
            int offset = 0;
            buffer.clear();
            while((length = fileChannel.read(buffer)) > 0) {
                buffer.flip();
                socketChannel.write(buffer);

                offset +=length;
                Logger.debug("| " + (100 * offset / file.length()) + "% |");
                buffer.clear();
            }
            //等待一分钟关闭连接
            ThreadUtil.sleepSeconds(60);

            if (length == -1) {
                IOUtil.closeQuietly(fileChannel);
                socketChannel.shutdownOutput();
                IOUtil.closeQuietly(socketChannel);
            }
            Logger.debug("======== 文件传输成功 ========");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    public static void main(String[] args) {
        NioSendClient client = new NioSendClient();
        client.sendFile();
    }

}
